﻿
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Labthink.PCSoft.UniversalHost4.Utility;

namespace Labthink.PCSoft.UniversalHost4.UserControls
{
    public partial class UcTextBox
    {
        public static readonly DependencyProperty LabelProperty = DependencyProperty.Register("Label", typeof(string), typeof(UcTextBox), new PropertyMetadata("Label", LabelChangedCallback));

        private static void LabelChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is UcTextBox txt)
            {
                txt.LabelChanged(e.NewValue + "");
            }
        }

        public int LabelMinWidth
        {
            get { return (int)GetValue(LabelMinWidthProperty); }
            set { SetValue(LabelMinWidthProperty, value); }
        }

        public static readonly DependencyProperty LabelMinWidthProperty =
            DependencyProperty.Register("LabelMinWidth", typeof(int), typeof(UcTextBox), new PropertyMetadata(0));

        public string Label
        {
            get => (string)GetValue(LabelProperty);
            set => SetValue(LabelProperty, value);
        }

        public static readonly DependencyProperty DescribeProperty = DependencyProperty.Register("Describe", typeof(string), typeof(UcTextBox), new PropertyMetadata("", DescribeChangedCallback));

        private static void DescribeChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is UcTextBox txt)
            {
                txt.DescribeChanged(e.NewValue + "");
            }
        }

        public string Describe
        {
            get => (string)GetValue(DescribeProperty);
            set => SetValue(DescribeProperty, value);
        }

        public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(string), typeof(UcTextBox), new PropertyMetadata(""));

        public string Value
        {
            get => (string)GetValue(ValueProperty);
            set => SetValue(ValueProperty, value);
        }

        public static readonly DependencyProperty DataTypeProperty = DependencyProperty.Register("DataType", typeof(DataType), typeof(UcTextBox), new PropertyMetadata(DataType.String));

        public DataType DataType
        {
            get => (DataType)GetValue(DataTypeProperty);
            set => SetValue(DataTypeProperty, value);
        }

        public static readonly DependencyProperty IsWarmProperty = DependencyProperty.Register("IsWarm", typeof(bool), typeof(UcTextBox), new PropertyMetadata(false, HasWarmChanged));

        private static void HasWarmChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            if (d is UcTextBox txt)
            {
                txt.ChangeWarm((bool)e.NewValue);
            }
        }

        public bool IsWarm
        {
            get => (bool)GetValue(IsWarmProperty);
            set => SetValue(IsWarmProperty, value);
        }

        public static readonly DependencyProperty MaxValueProperty = DependencyProperty.Register("MaxValue", typeof(double), typeof(UcTextBox), new PropertyMetadata(double.MaxValue));

        public double MaxValue
        {
            get => (double)GetValue(MaxValueProperty);
            set => SetValue(MaxValueProperty, value);
        }

        public static readonly DependencyProperty MinValueProperty = DependencyProperty.Register("MinValue", typeof(double), typeof(UcTextBox), new PropertyMetadata(double.MinValue));

        public double MinValue
        {
            get => (double)GetValue(MinValueProperty);
            set => SetValue(MinValueProperty, value);
        }

        public static readonly DependencyProperty RegProperty = DependencyProperty.Register("Reg", typeof(string), typeof(UcTextBox), new PropertyMetadata(""));

        public string Reg
        {
            get => (string)GetValue(RegProperty);
            set => SetValue(RegProperty, value);
        }

        public static readonly DependencyProperty MaxLengthProperty = DependencyProperty.Register("MaxLength", typeof(double), typeof(UcTextBox), new PropertyMetadata(65535.0));

        public double MaxLength
        {
            get => (double)GetValue(MaxLengthProperty);
            set => SetValue(MaxLengthProperty, value);
        }

        public static readonly DependencyProperty MinLengthProperty = DependencyProperty.Register("MinLength", typeof(double), typeof(UcTextBox), new PropertyMetadata(-1.0));

        public double MinLength
        {
            get => (double)GetValue(MinLengthProperty);
            set => SetValue(MinLengthProperty, value);
        }

        public const string RegInt = @"^-?[0-9]\d*$";
        public const string RegDouble = @"^-?[0-9]+([.]{1}[0-9]+){0,1}$";
        private System.Windows.Media.Brush _tmpBrush;
        private string _tmpValue;

        public UcTextBox()
        {
            InitializeComponent();
            DataContext = this;
            _tmpBrush = Txt.BorderBrush;
            _tmpValue = Txt.Text;
        }

        private void Txt_OnGotFocus(object sender, RoutedEventArgs e)
        {
            Txt.BorderBrush = _tmpBrush;
            _tmpValue = Txt.Text;
        }

        public void ChangeWarm(bool warm)
        {
            if (warm)
            {
                _tmpBrush = Txt.BorderBrush;
                Txt.BorderBrush = System.Windows.Media.Brushes.Red;
            }
            else
            {
                Txt.BorderBrush = _tmpBrush;
            }
        }

        private void Txt_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            //Txt.Focus();
            pop1.IsOpen = false;
            pop1.IsOpen = true;
            pop1.StaysOpen = false;
            pop1.StaysOpen = true;
            //Txt1.Focus();
        }

        private void Txt_PreviewTouchDown(object sender, TouchEventArgs e)
        {
            //Txt.Focus();
            pop1.IsOpen = false;
            pop1.IsOpen = true;
            pop1.StaysOpen = false;
            pop1.StaysOpen = true;
            //Txt1.Focus();
        }

        public void Txt_OnLostFocus(object sender, RoutedEventArgs e)
        {
            if(!Txt1.IsFocused)pop1.StaysOpen = false;
            //Txt1.Focus();
            //if (string.IsNullOrEmpty(Txt.Text)) return;
            if (DataType == DataType.String)
            {
                if (MinLength >= 0 && Txt.Text.Length < MinLength)
                {
                    _tmpBrush = Txt.BorderBrush;
                    Txt.BorderBrush = System.Windows.Media.Brushes.Red;
                }

                if (Txt.Text.Length > MaxLength)
                {
                    _tmpBrush = Txt.BorderBrush;
                    Txt.BorderBrush = System.Windows.Media.Brushes.Red;
                    Txt.Text = Txt.Text.Substring(0, MaxLength.ToInt());
                }

                if (string.IsNullOrEmpty(Reg) || string.IsNullOrEmpty(Txt.Text)) return;
                if (!Regex.IsMatch(Txt.Text, Reg)) Txt.Text = Txt.Text = _tmpValue;
            }
            else if (DataType == DataType.Int)
            {
                if (!Regex.IsMatch(Txt.Text, RegInt))
                {
                    Txt.Text = _tmpValue;
                    _tmpBrush = Txt.BorderBrush;
                    Txt.BorderBrush = System.Windows.Media.Brushes.Red;
                }
                else
                {
                    var v = Txt.Text.ToInt();
                    if (v > MaxValue) Txt.Text = MaxValue.ToInt() + "";
                    else if (v < MinValue) Txt.Text = MinValue.ToInt() + "";
                }
            }
            else
            {
                if (!Regex.IsMatch(Txt.Text, RegDouble))
                {
                    Txt.Text = _tmpValue;
                    _tmpBrush = Txt.BorderBrush;
                    Txt.BorderBrush = System.Windows.Media.Brushes.Red;
                }
                else
                {
                    var v = Txt.Text.ToDouble();
                    if (v > MaxValue) Txt.Text = MaxValue + "";
                    else if (v < MinValue) Txt.Text = MinValue + "";
                }
            }
        }

        public void Txt1_OnLostFocus(object sender, RoutedEventArgs e)
        {
            pop1.StaysOpen = false;
            pop1.IsOpen = false;
        }
        private void UcTextBox_OnLoaded(object sender, RoutedEventArgs e)
        {
            if (ActualHeight > 60)
            {
                Txt.TextWrapping = TextWrapping.Wrap;
            }
        }

        private void Txt_OnTextChanged(object sender, TextChangedEventArgs e)
        {
            //Value = Txt.Text;
            if (sender is TextBox txt)
            {
                if (txt.Text != Txt.Text) Txt.Text = txt.Text;
                if (txt.Text != Txt1.Text) Txt1.Text = txt.Text;
            }
        }

        public void ChangeBorderBrush(System.Windows.Media.Brush b)
        {
            Txt.BorderBrush = b;
        }

        public void LabelChanged(string label)
        {
            TxtttName.Text = label;
            Sptt.Visibility = string.IsNullOrEmpty(label) ? Visibility.Collapsed : Visibility.Visible;
        }

        public void DescribeChanged(string label)
        {
            TxtttDesc.Text = label;
            Sptt.Visibility = string.IsNullOrEmpty(label) ? Visibility.Collapsed : Visibility.Visible;
        }

        private void pop1_Opened(object sender, System.EventArgs e)
        {
            //Txt1.Focus();
        }

        private void pop1_Loaded(object sender, RoutedEventArgs e)
        {
            Txt1.Focus();
        }
    }

    public enum DataType
    {
        Int,
        Double,
        String
    }
}
